from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash

from flaskLogin.extensions import db

from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy import String, ForeignKey, JSON, UUID, DateTime, SmallInteger,BOOLEAN


class Account(db.Model, UserMixin):  # user表似乎和postgresql有点冲突，所以换个命名
    __tablename__ = 'account'
    id: Mapped[int] = mapped_column(primary_key=True)
    userid = mapped_column(String(32), comment='账号', unique=True, index=True)
    password_hash = mapped_column(String(256), comment='密码_hash')
    alternative_id = mapped_column(UUID, comment='token', unique=True, index=True)
    username = mapped_column(String(32), comment='姓名')
    department = mapped_column(String(32), comment='部门')
    is_admin: Mapped[bool] = mapped_column(BOOLEAN, comment='是否为管理员', default=False)
    last_login = mapped_column(DateTime, comment='最后在线时间')

    # 替换为token验证，只允许单台设备登录
    def get_id(self):
        return str(self.alternative_id)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def validate_password(self, password):
        return check_password_hash(self.password_hash, password)


class Account_logging(db.Model):  # 登录日志
    __tablename__ = 'account_logging'
    id: Mapped[int] = mapped_column(primary_key=True)
    c_date = mapped_column(String(32), comment='登录/出时间')
    loginkind = mapped_column(SmallInteger, comment='0=登录，1=登出', default=0)
    alternative_id = mapped_column(UUID, comment='token')
    account_id = mapped_column(ForeignKey("account.id"))  # 外键


class Note(db.Model):
    __tablename__ = 'note'
    id: Mapped[int] = mapped_column(primary_key=True)
    fake_uuid = mapped_column(UUID)  # uuid列必须一开始指定该类型，从string转会报错
    fake_name: Mapped[str] = mapped_column(String(64), comment='随机虚拟名字')
    this_json = mapped_column(JSON)  # 随意建的

    note_details = relationship("Note_detail", backref="note")  # backref简化双向关系，为另一侧添加关系属性，作为反向引用


class Note_detail(db.Model):
    __tablename__ = 'note_detail'
    id: Mapped[int] = mapped_column(primary_key=True)
    fake_email = db.Column(db.String(256))
    c_date = db.Column(db.DateTime)

    note_id = mapped_column(ForeignKey("note.id"))
